<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="shortcut icon" href="">
        <title>Canvas tutorial</title>
        <style type="text/css">
           body {
              background-color: #eccc68;
            }
            canvas {
              width: 400px;
              height: 300px;
              border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <h1>Snake</h1>
        <canvas id="canvas" width="800" height="600"></canvas>
        <script type="text/javascript">
            ;(function(){
                let side = 20;
                Game = {
                    tmp: 0,
                    side: side,
                    left: 0,
                    right: 800 - side,
                    top: 0,
                    bottom: 600 - side,
                    tickLength: 100, 				// 20Hz
                    lastTick: performance.now(),	// 最后更新时间
                    stopKey: 0
                }
                Snake = {
                    len: 3,
                    snakex: [4 * Game.side, 3 * Game.side, 2 * Game.side],
                    snakey: [3 * Game.side, 3 * Game.side, 3 * Game.side],
                    direct: 3,
                }
                Food = {
                    position: {
          	            x: Math.floor(Math.random() * Game.right / Game.side) * Game.side,
          	            y: Math.floor(Math.random() * Game.bottom / Game.side) * Game.side
          	            }
                }
                function main(tFrame) {
                    Game.stopKey = requestAnimationFrame(main);
                    let canvas = document.querySelector("#canvas");
                    let ctx = canvas.getContext('2d');
                    let nextTick = Game.lastTick + Game.tickLength;
                    let numTicks = 0;
                    if (tFrame > nextTick) {
                        numTicks = Math.floor((tFrame - Game.lastTick) / Game.tickLength)
                    }
                  	queueUpdate(numTicks);
                    draw(ctx);
                }
                Game.lastTick = performance.now();
                main(performance.now());
                document.addEventListener("keydown", keydownHandler, false);
            })();
            function keydownHandler(e) {
                if(e.key == "w") {
                    Snake.direct = 0;
                }
                else if(e.key == "s") {
                    Snake.direct = 1;
                }
                else if(e.key == "a") {
                    Snake.direct = 2;
                }
                else if(e.key == "d") {
                    Snake.direct = 3;
                }
            }
            function queueUpdate(numTicks) {
                for (let i = 0; i < numTicks; i++) {
                    update(numTicks)
                }
            }
            function update(numTicks) {
                /*
                Game.tmp += Game.side
              	if (Game.tmp > 800 || Game.tmp < 0) {
                    Game.side *= -1;
              	}
              	*/
              	for (let i = Snake.len - 1; i >= 1; i--) {
              	    Snake.snakex[i] = Snake.snakex[i - 1]
              	    Snake.snakey[i] = Snake.snakey[i - 1]
              	}
              	if (Snake.direct === 0) {
          	        Snake.snakey[0] -= Game.side;
              	} else if (Snake.direct === 1) {
          	        Snake.snakey[0] += Game.side;
              	} else if (Snake.direct === 2) {
          	        Snake.snakex[0] -= Game.side;
              	} else if (Snake.direct === 3) {
          	        Snake.snakex[0] += Game.side;
              	}
          	    if (Snake.snakex[0] > Game.right){
          	        Snake.snakex[0] = Game.left;
          	    }
          	    if (Snake.snakex[0] < Game.left) {
          	        Snake.snakex[0] = Game.right;
          	    }
          	    if (Snake.snakey[0] > Game.bottom){
          	        Snake.snakey[0] = Game.top;
          	    }
          	    if (Snake.snakey[0] < Game.top) {
          	        Snake.snakey[0] = Game.bottom;
          	    }
          	    if (Snake.snakex[0] === Food.position.x && Snake.snakey[0] === Food.position.y) {
          	        Food.position = {
          	            x: Math.floor(Math.random() * Game.right / Game.side) * Game.side,
          	            y: Math.floor(Math.random() * Game.bottom / Game.side) * Game.side
          	            }
          	        Snake.len++;
          	        console.log(Food.position)
          	    }
          	    Game.lastTick += Game.tickLength;
            }
            function draw(ctx) {
                let side = 10;
                ctx.fillStyle = '#eccc68'
                ctx.fillRect(0, 0, 800, 600);
                ctx.beginPath();
                // 网格
                /*
                for (let i = 10; i < 800; i+=side) {
                    ctx.moveTo(i,0);
                    ctx.lineTo(i,600);
                }
                for (let i = 10; i < 600; i+=side) {
                    ctx.moveTo(0,i);
                    ctx.lineTo(800, i);
                }
                */
                /*
                for (let i = 10; i < Game.tmp; i+=10) {
                    ctx.moveTo(i,0);
                    ctx.lineTo(800, i);
                }
                */
                ctx.closePath();
                ctx.strikeStyle = 'rgb(255,165,0)';
                ctx.stroke();

                // 蛇身
                for (let i = Snake.len - 1; i >= 0; i--) {
                    if (i > 0) {
                        ctx.fillStyle = '#747d8c';
                    } else {
                        ctx.fillStyle = '#2f3542';
                    }
                    ctx.fillRect(Snake.snakex[i], Snake.snakey[i], Game.side, Game.side);
                }
                // 食物
                ctx.fillRect(Food.position.x, Food.position.y, Game.side, Game.side);
                /*
                ctx.beginPath();
                ctx.moveTo(Food.position.x, Food.position.y);
                ctx.arc(Food.position.x, Food.position.y, Game.side / 2, 0, Math.PI * 2, true);
                ctx.closePath();
                ctx.fillStyle = '#ff6b81'
                ctx.fill();
                */
            }
        </script>
    </body>
</html>
